import time
from abc import ABC, abstractmethod
import requests

from user.models import SfUser, UserModel
from user.ser import SfUserSer, UserSer
from utils.MyJWT import myjwt
from utils.myjwtt import mjwt


class Factory(ABC):
    @abstractmethod
    def geturl(self):
        pass

    @abstractmethod
    def callback(self, request):
        pass


class Dingdinglogin(Factory):
    def __init__(self) -> None:
        self.client_id = 'dingm72r6z8dv8pi3efu'
        self.clientSecret = 'gH8_e9zPz3fYwNHKEPpuyFkAGb6W8XubvH9AvvkHBUx52e34x7Q3xCFjl0eU4Yap'

    def geturl(self):
        from urllib.parse import quote
        params = [
            f"redirect_uri={quote('http://127.0.0.1:8000/user/dingtalkCallback/?types=dingding')}",
            "response_type=code",
            "client_id=" + self.client_id,
            "scope=openid",
            "prompt=consent"
        ]
        url = "https://login.dingtalk.com/oauth2/auth?" + ("&".join(params))
        return {"url": url}

    def callback(self, request):
        # 钉钉操作
        authCode = request.query_params.get('code')
        print(authCode)
        # 根据authCode获取用户accessToken
        data = {
            "clientId": self.client_id,
            "clientSecret": self.clientSecret,
            "code": authCode,
            "grantType": "authorization_code"
        }
        resp = requests.post('https://api.dingtalk.com/v1.0/oauth2/userAccessToken', json=data).json()
        accessToken = resp.get('accessToken')

        # 根据accessToken获取用户信息
        headers = {"x-acs-dingtalk-access-token": accessToken}
        resp = requests.get('https://api.dingtalk.com/v1.0/contact/users/me', headers=headers).json()
        print(resp)
        name = resp.get('nick')
        uid = resp.get('openId')
        phone = resp.get('mobile')

        # 登录，写入三方登录表和用户表
        sfl = SfUser.objects.filter(uid=uid, type='dingding').first()
        if not sfl:
            # 写入用户表
            # 手机号用户存在直接绑定,不存在注册新用户
            user = UserModel.objects.filter(phone=phone).first()
            if not user:
                userinfo = {
                    "name": name,
                    "phone": phone,
                    "username": phone
                }
                us =UserSer(data=userinfo)
                if us.is_valid():
                    user = us.save()
                else:
                    # , "msg": tostr(us.errors)
                    return {"code": 10001}
            # 写入三方登录表
            sfinfo = {
                "token": accessToken,
                "uid": uid,
                "user": user.id,
                'type': 'dingding'
            }
            sfs = SfUserSer(data=sfinfo)
            if sfs.is_valid():
                sfs.save()
            else:
                # "msg": tostr(sfs.errors)
                print(sfs.errors)
                return {"code": 10001}
        else:
            user = sfl.user
            sfl.token = accessToken
            sfl.save()

        # 生成jwt token并返回前端
        payload = {"id": user.id, "username": user.username, "exp": int(time.time()) + 60 * 60 * 2}
        token = "Bearer " +mjwt.jwt_encode(payload)
        payload["exp"] = int(time.time() + 60 * 60 * 24 * 2)
        refreshToken = "Bearer "+mjwt.jwt_encode(payload)
        query = [f"userid={payload['id']}", f"token={token}",
                 f"reToken={refreshToken}"]
        return f'http://localhost:8080/?{"&".join(query)}'


class SFlogin:
    def create_factory(self, params):
        # getattr  setattr
        if params == 'dingding':
            dingding = Dingdinglogin()
            return dingding

        elif params == 'weibo':
            return


sflogin = SFlogin()
